/***************************************************************************
 *   Copyright (C) 2008 by Thomas Fannes                                   *
 *   thomasfannes@gmail.com                                                *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "Board.h"
#include "Tile.h"
#include "CornerBuilding.h"
#include "SideBuilding.h"
#include "Player.h"

namespace board
{
	Board::Board()
	{
	}

	Board::Board(const BoardDescription & description)
	{
	}

	Board::~Board()
	{
	}

	void Board::clean()
	{
		// remove all the tiles
		for (QVector<Tile *>::iterator i = arTiles.begin(); i != arTiles.end(); i++)
		{
			(*i)->getHexagon()->setUserData(0);
			delete (*i);
			(*i) = 0;
		}
		arTiles.clear();

		// remove all the buildings
		for (QVector<CornerBuilding *>::iterator i = arCornerBuildings.begin(); i != arCornerBuildings.end(); i++)
		{
			(*i)->getCorner()->setUserData(0);
			delete (*i);
			(*i) = 0;
		}
		arCornerBuildings.clear();

		// remove all the buildings
		for (QVector<SideBuilding *>::iterator i = arSideBuildings.begin(); i != arSideBuildings.end(); i++)
		{
			(*i)->getSide()->setUserData(0);
			delete (*i);
			(*i) = 0;
		}
		arSideBuildings.clear();
	}

	BoardDescription Board::getDescription() const
	{
		BoardDescription desc;

		for (QVector<Tile *>::const_iterator i = arTiles.begin(); i != arTiles.end(); i++)
			desc.arTiles.push_back((*i)->getDescription());

		for (QVector<SideBuilding *>::const_iterator i = arSideBuildings.begin(); i != arSideBuildings.end(); i++)
			desc.arSideBuildings.push_back((*i)->getDescription());

		for (QVector<CornerBuilding *>::const_iterator i = arCornerBuildings.begin(); i != arCornerBuildings.end(); i++)
			desc.arCornerBuildings.push_back((*i)->getDescription());

		return desc;
	}

	Tile * Board::setTile(const structure::HexVector & position, TileData data)
	{
		structure::Hexagon * hexagon = grid.createHexagon(position);
		Tile * tile = hexagon->getUserData<Tile> ();

		if (tile == 0)
		{
			// create new tile
			tile = new Tile(hexagon, data);
			arTiles.push_back(tile);
		}
		else
		{
			// update the tile
			tile->setData(data);
		}

		return tile;
	}

	SideBuilding * Board::setSideBuilding(const structure::HexVector & position, SideBuildingData data, Player * player)
	{
		if (player != 0)
			data.playerID = player->getPlayerID();

		structure::Side * side = grid.createSide(position);
		SideBuilding * building = side->getUserData<SideBuilding> ();

		if (building == 0)
		{
			// create a new sideBuilding
			building = new SideBuilding(side, data);
			arSideBuildings.push_back(building);
		}
		else
		{
			// update the building
			building->setData(data);
		}

		return building;
	}

	CornerBuilding * Board::setCornerBuilding(const structure::HexVector & position, CornerBuildingData data, Player * player)
	{
		if (player != 0)
			data.playerID = player->getPlayerID();

		structure::Corner * corner = grid.createCorner(position);
		CornerBuilding * building = corner->getUserData<CornerBuilding> ();

		if (building == 0)
		{
			// create a new sideBuilding
			building = new CornerBuilding(corner, data);
			arCornerBuildings.push_back(building);
		}
		else
		{
			// update the building
			building->setData(data);
		}

		return building;
	}

	Player * Board::setPlayer(unsigned int playerID, const QString & name)
	{
	}

	void Board::removeTile(const structure::HexVector & position)
	{
		Tile * tile = getTileAt(position);

		if (tile == 0)
			return;

		arTiles.remove(arTiles.indexOf(tile));
		tile->getHexagon()->setUserData(0);
		delete tile;
	}

	void Board::removeSideBuilding(const structure::HexVector & position)
	{
		SideBuilding * sideBuilding = getSideBuildingAt(position);

		if (sideBuilding == 0)
			return;

		arSideBuildings.remove(arSideBuildings.indexOf(sideBuilding));
		sideBuilding->getSide()->setUserData(0);
		delete sideBuilding;
	}

	void Board::removeCornerBuilding(const structure::HexVector & position)
	{
		CornerBuilding * cornerBuilding = getCornerBuildingAt(position);

		if (cornerBuilding == 0)
			return;

		arCornerBuildings.remove(arCornerBuildings.indexOf(cornerBuilding));
		cornerBuilding->getCorner()->setUserData(0);
		delete cornerBuilding;
	}

	Tile * Board::getTileAt(const structure::HexVector & position) const
	{
		if(structure::HexGrid::CheckLocationType(position) != structure::GridLocationHexagon)
			return 0;

		return grid.getHexagonAt(position)->getUserData<Tile>();
	}
	SideBuilding * Board::getSideBuildingAt(const structure::HexVector & position) const
	{
		if(structure::HexGrid::CheckLocationType(position) != structure::GridLocationSide)
			return 0;

		return grid.getSideAt(position)->getUserData<SideBuilding>();
	}
	CornerBuilding * Board::getCornerBuildingAt(const structure::HexVector & position) const
	{
		if(structure::HexGrid::CheckLocationType(position) != structure::GridLocationCorner)
			return 0;

		return grid.getCornerAt(position)->getUserData<CornerBuilding>();
	}
}
